package com.liankuan.console.service.ServiceImpl;

import com.google.common.collect.Lists;
import com.liankuan.console.common.ResultEnum;
import com.liankuan.console.controller.vo.UserInfoVO;
import com.liankuan.console.controller.vo.request.User.UserDtoIO;
import com.liankuan.console.controller.vo.request.User.UserStrategyIO;
import com.liankuan.console.controller.vo.user.UserDtoVO;
import com.liankuan.console.controller.vo.user.UserListVO;
import com.liankuan.console.controller.vo.user.UserStrategyListVO;
import com.liankuan.console.controller.vo.user.UserStrategyVO;
import com.liankuan.console.dto.User;
import com.liankuan.console.dto.UserRole;
import com.liankuan.console.dto.UserStrategy;
import com.liankuan.console.exception.ServiceException;
import com.liankuan.console.repository.UserExchangeRepository;
import com.liankuan.console.repository.UserRepository;
import com.liankuan.console.repository.UserStrategyRepository;
import com.liankuan.console.service.UserService;
import com.liankuan.console.util.DES;
import com.liankuan.console.util.TokenProccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    private UserRepository userRepository;
    private UserRoleServiceImpl userRoleService;
    private UserExchangeRepository userExchangeRepository;
    private UserStrategyRepository userStrategyRepository;

    @Autowired
    public UserServiceImpl(UserRepository userRepository, UserRoleServiceImpl userRoleService, UserExchangeRepository
            userExchangeRepository, UserStrategyRepository userStrategyRepository) {
        this.userRepository = userRepository;
        this.userRoleService = userRoleService;
        this.userExchangeRepository = userExchangeRepository;
        this.userStrategyRepository = userStrategyRepository;
    }

    /**
     * 验证用户登录
     *
     * @param name
     * @param password
     * @return
     */
    @Override
    public String login(String name, String password) {
        //md5对用户名进行加密处理
        String md5Password = DES.getMD5String(password);
        User user = userRepository.findByNameAndPassword(name, md5Password);
        if (user == null) {
            throw new ServiceException(ResultEnum.LOGIN_FAILES);
        }

        //将该用户的更新token存入
        String token = TokenProccessor.makeToken();
        userRepository.updateUserToken(user.getId(), token);
        return token;
    }

    /**
     * 用户退出登陆
     *
     * @param token
     */
    @Override
    public void logout(String token) {
        User user = userRepository.findByToken(token);

        // TODO 将用户TOKEN设置为空
//        userRepository.updateUserToken(user.getId(), "");
    }

    /**
     * 根据token获取该用户信息
     *
     * @param token
     * @return
     */
    @Override
    public User getUserInfoByToken(String token) {
        return userRepository.findByToken(token);
    }

    /**
     * 获取所以用户对于某一个策略的对应关系
     *
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public UserStrategyListVO listUsersWithStrategy(Integer currentPage, Integer pageSize, Integer strategyId) {
        //因为page从0开始的--》所以传过来的页面减一 (按照id降序排列)
        Pageable pageable = new PageRequest(currentPage - 1, pageSize, Sort.Direction.DESC, "id");
        Page<User> users = userRepository.findAll(pageable);

        //定义返回的数据
        UserStrategyListVO userStrategyListVO = new UserStrategyListVO();

        List<User> userList = users.getContent();
        List<UserStrategyVO> list = new ArrayList<>();
        for (User user : userList) {
            //排序创建----需要过滤掉admin用户自己
            if ("admin".equals(user.getName())) {
                continue;
            }
            //获取用户对应的和该策略的关系数据
            UserStrategy userStrategy = userStrategyRepository.findByUserIdAndStrategyId(user.getId(), strategyId);

            list.add(new UserStrategyVO(user, userStrategy));
        }

        userStrategyListVO.setList(list);
        userStrategyListVO.setTotal(users.getTotalElements());

        return userStrategyListVO;
    }

    /**
     * 更新用户和某条策略之间的关系
     *
     * @param userStrategyIO
     */
    @Override
    @Transactional
    public void updateUserStrategy(UserStrategyIO userStrategyIO) {
        //首先判断该记录在表中是否存在
        UserStrategy userStrategy = userStrategyRepository.findByUserIdAndStrategyId(userStrategyIO.getUserId(),
                userStrategyIO.getStrategyId());

        if (userStrategy != null) {
            if (userStrategyIO.getLevel() == 4) {
                //代表设置为无权----》则将该记录在表中删除即可
                userStrategyRepository.deleteAllByUserIdAndStrategyId(userStrategyIO.getUserId(), userStrategyIO
                        .getStrategyId());
                return;
            }
            //进行更新操作就好
            userStrategyRepository.updateByUserIdAndStrategyId(userStrategyIO.getLevel(), userStrategyIO.getUserId(),
                    userStrategyIO.getStrategyId());

        } else {
            if (userStrategyIO.getLevel() == 4) {
                //代表没有该记录--->设置为无权无需新增
                return;
            }
            //进行新增
            userStrategyRepository.save(new UserStrategy(userStrategyIO));
        }


    }

    /**
     * 通过用户名盘点给用户是否存在
     *
     * @param name
     * @return
     */
    @Override
    public boolean getUserInfoByName(String name) {
        User user = userRepository.findByName(name);
        if (user != null) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据用户id获取信息
     *
     * @param userId
     * @return
     */
    @Override
    public User findUserById(int userId) {
        return userRepository.findOne(userId);
    }

    @Override
    @Transactional
    public void updateMyselfInfo(UserDtoIO userDtoIO) {
        //先获取用户库中信息，判断密码是否一致，如果一样则不改动
        User user = userRepository.findOne(userDtoIO.getId());
        String md5Password = DES.getMD5String(userDtoIO.getPassword());

        if (user.getPassword().equals(userDtoIO.getPassword())) {
            userRepository.updateUserInfo(userDtoIO.getId(), userDtoIO.getName(), userDtoIO.getPassword());
        } else {
            userRepository.updateUserInfo(userDtoIO.getId(), userDtoIO.getName(), md5Password);
        }
    }

    /**
     * 获取用户权限信息
     *
     * @param token
     * @return
     */
    @Override
    public UserInfoVO getInfo(String token) {
        UserInfoVO userInfoVO = new UserInfoVO();
        User user = userRepository.findByToken(token);
        userInfoVO.setName(user.getName());
        UserRole userRole = userRoleService.findRoleByUserId(user.getId());

        // TODO(获取用户信息暂时先写死后期修改)
        userInfoVO.setRoles(Lists.newArrayList(userRole.getRole()));
        userInfoVO.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        return userInfoVO;
    }

    /**
     * 获取所有用户列表信息
     *
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public UserListVO listUsers(Integer currentPage, Integer pageSize) {
        //因为pageshi从0开始的--》所以传过来的页面减一
        Pageable pageable = new PageRequest(currentPage - 1, pageSize);

        Page<User> users = userRepository.findAll(pageable);
        UserListVO userListVO = new UserListVO();

        List<UserDtoVO> list = users.getContent().stream().map(record -> {
            UserDtoVO userDtoVO = new UserDtoVO(record);
            //获取用户对应的角色权限
            UserRole userRole = userRoleService.findRoleByUserId(record.getId());
            userDtoVO.setRole(userRole.getRole());

            return userDtoVO;
        }).collect(Collectors.toList());

        userListVO.setList(list);
        userListVO.setTotal(users.getTotalElements());
        return userListVO;
    }

    /**
     * 删除用户信息
     *
     * @param id
     */
    @Override
    @Transactional
    public void deleteUser(Integer id) {
        // TODO 其实还应该删除所有的对应的策略表和交易所表中的数据

        //1.删除用户对应的角色信息
        userRoleService.deleteByUserId(id);

        //2.删除用户对应交易所关联表
        userExchangeRepository.deleteAllByUserId(id);

        //3.删除用户对应策略关联表
        userStrategyRepository.deleteAllByUserId(id);

        //4.删除用户表
        userRepository.delete(id);
    }


    /**
     * 更新用户信息
     *
     * @param userDtoIO
     */
    @Override
    @Transactional
    public void updateUser(UserDtoIO userDtoIO) {
        //先更新用户角色表
        userRoleService.updateByUserId(userDtoIO.getId(), userDtoIO.getRole());

        //先获取用户库中信息，判断密码是否一致，如果一样则不改动
        User user = userRepository.findOne(userDtoIO.getId());
        String md5Password = DES.getMD5String(userDtoIO.getPassword());

        if (user.getPassword().equals(userDtoIO.getPassword())) {
            userRepository.updateUserInfo(userDtoIO.getId(), userDtoIO.getName(), userDtoIO.getPassword());
        } else {
            userRepository.updateUserInfo(userDtoIO.getId(), userDtoIO.getName(), md5Password);
        }
    }

    /**
     * 新增用户信息
     *
     * @param userDtoIO
     */
    @Override
    @Transactional
    public void addUser(UserDtoIO userDtoIO) {
        User user = new User(userDtoIO);
        //对用户的密码进行加密处理
        String md5Password = DES.getMD5String(userDtoIO.getPassword());
        user.setPassword(md5Password);
        userRepository.save(user);


        //存储用户的角色信息
        userRoleService.addUserRole(user.getId(), userDtoIO.getRole());
    }


}
